﻿
//结构体定义信息分析类
namespace n_PyStruct
{
using System;
using n_PyET;
using n_PyMemberType;
using n_PyParse;
using n_PyParseNet;
using n_PyStructList;
using n_PyStructNode;
using n_PyWordList;
using n_PyConfig;
using n_PyStructLink;

public static class Struct
{
	static string UnitName;
	static int NameIndex;
	
	//获取元件信息,生成: 元件列表 函数列表 变量列表
	public static void Record()
	{
		//结构体列表初始化
		StructList.Clear();
		NameIndex = 0;
		
		Parse.DealWith( ref UnitName, new Parse.MemberListHandle( 成员列表 ) );
	}
	
	static void 成员列表( int Index )
	{
		for( int i = 1; i < ParseNet.NodeSet[ Index ].Length; ++i ) {
			int index = int.Parse( ParseNet.NodeSet[ Index ][ i ] );
			
			//判断是否元件定义
			if( ParseNet.NodeSet[ index ][ 0 ] == ParseNet.Node.元件 ) {
				元件( index );
				continue;
			}
			if( ParseNet.NodeSet[ index ][ 0 ] == ParseNet.Node.结构体定义 ) {
				结构体( index );
				continue;
			}
		}
	}
	
	static void 元件( int Index )
	{
		Parse.Unit( ref UnitName, Index, new Parse.MemberListHandle( 成员列表 ) );
	}
	
	static void 结构体( int Index )
	{
		//获取成员类型
		string VisitType = null;
		string RealRefType = null;
		int MemberTypeIndex = int.Parse( ParseNet.NodeSet[ Index ][ 1 ] );
		Parse.GetMemberType( MemberTypeIndex, ref VisitType, ref RealRefType );
		
		//获取结构体名称
		int NameIndex = int.Parse( ParseNet.NodeSet[ Index ][ 3 ] );
		string StructName = UnitName + "." + WordList.GetWord( NameIndex );
		if( StructList.GetDirectIndex( StructName ) != -1 ) {
			ET.WriteParseError( NameIndex, "当前的名称空间已经有同名的结构体类型: " + UnitName + "." + StructName );
			return;
		}
		StructNode node = null;
		
		//获取结构体成员列表
		int TypeIndex = int.Parse( ParseNet.NodeSet[ Index ][ 4 ] );
		int MemberIndex = int.Parse( ParseNet.NodeSet[ TypeIndex ][ 2 ] );
		
		int MemberNumber = ParseNet.NodeSet[ MemberIndex ].Length - 1;
		if( MemberNumber == 0 && RealRefType == MemberType.RealRefType.Real ) {
			ET.WriteParseError( NameIndex, "结构体的成员不能为空: " + UnitName + "." + StructName );
			return;
		}
		MemberNode[] MemberList = AddNewStruct( MemberIndex );
		if( MemberList == null ) {
			return;
		}
		node = new StructNode( VisitType, RealRefType, StructName, MemberList, UnitName, NameIndex );
		StructList.Add( node );
		
		//处理链接类型
		int LinkIndex = int.Parse( ParseNet.NodeSet[ Index ][ 5 ] );
		if( LinkIndex != -1 ) {
			//提取第二个成员信息
			int SecondIndex = int.Parse( ParseNet.NodeSet[ LinkIndex ][ 2 ] );
			int ErrorIndex2 = 0;
			string SecondName = null;
			Parse.GetMemberNames( UnitName, SecondIndex, ref SecondName, ref ErrorIndex2 );
			if( RealRefType != MemberType.RealRefType.link ) {
				ET.WriteParseError( int.Parse( ParseNet.NodeSet[ Index ][ 4 ] ), "连接器的左端必须为引用类型成员:" + UnitName );
			}
			node.TargetMemberName = SecondName;
		}
	}
	
	//添加并检查结构体类型
	public static string AddNewStructAndCheck( int MemberIndex, string UnitName )
	{
		int MemberNumber = ParseNet.NodeSet[ MemberIndex ].Length - 1;
		MemberNode[] MemberList = AddNewStruct( MemberIndex );
		if( MemberList == null ) {
			return null;
		}
		string StructName = NameIndex.ToString();
		++NameIndex;
		StructNode node = new StructNode( MemberType.VisitType.Private, MemberType.RealRefType.Real,
		                                 StructName, MemberList, UnitName, 0 );
		StructList.Add( node );
		StructLink.StandardStructList();
		return StructName;
	}
	
	//添加新的结构体类型
	static MemberNode[] AddNewStruct( int MemberIndex )
	{
		int MemberNumber = ParseNet.NodeSet[ MemberIndex ].Length - 1;
		MemberNode[] MemberList = new MemberNode[ MemberNumber ];
		string MemberNameList = ",";
		for( int j = 1; j < ParseNet.NodeSet[ MemberIndex ].Length; ++j ) {
			int member = int.Parse( ParseNet.NodeSet[ MemberIndex ][ j ] );
			
			int MemberLocation = int.Parse( ParseNet.NodeSet[ member ][ 2 ] );
			string MemberName = WordList.GetWord( MemberLocation );
			if( MemberNameList.IndexOf( "," + MemberName + "," ) != -1 ) {
				ET.WriteParseError( MemberLocation, "结构体的这个成员已经定义过: " + MemberName );
			}
			MemberNameList += MemberName + ",";
			int TypeIndex = int.Parse( ParseNet.NodeSet[ member ][ 1 ] );
			MemberList[ j - 1 ] = new MemberNode( TypeIndex, MemberName, MemberLocation );
		}
		return MemberList;
	}
}
}
